﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Caching;
using Volo.Abp.Json;
using Volo.Abp.Users;

namespace TianShu.WebApi.ApiFilters
{
    public class RepeatCommitFilter : IAsyncActionFilter
    {
        private readonly IJsonSerializer _jsonSerializer;
        private readonly IDistributedCache<string> _repeatCommitCache;
        private readonly ICurrentUser _currentUser;
        private readonly IOptions<RepeatCommitOptions> _repeatCommitOptions;

        public RepeatCommitFilter(IJsonSerializer jsonSerializer, IDistributedCache<string> repeatCommitCache, ICurrentUser currentUser, IOptions<RepeatCommitOptions> repeatCommitOptions)
        {
            _jsonSerializer = jsonSerializer;
            _repeatCommitCache = repeatCommitCache;
            _currentUser = currentUser;
            _repeatCommitOptions = repeatCommitOptions;
        }

        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            if (_repeatCommitOptions.Value.InterceptRequestMethods.Any(e => e.ToLower() == context.HttpContext.Request.Method.ToLower()))
            {
                var reqUrl = context.HttpContext.Request.Path.Value;
                var argStr = _jsonSerializer.Serialize(context.ActionArguments);
                var reqIpAddress = context.HttpContext.Connection.RemoteIpAddress.ToString();
                var userAgentStr = context.HttpContext.Request.Headers["User-Agent"];

                var reqInfo = $"{reqUrl}_{argStr}_{reqIpAddress}_{userAgentStr}_{_currentUser.Id}";

                var cacheKey = $"RepeatCommit_{reqInfo.ToMd5()}";

                var repeatCommitData = await _repeatCommitCache.GetAsync(cacheKey);
                if (repeatCommitData.IsNoNullAndNoEmpty())
                {
                    context.Result = new JsonResult(new ResultDto<object>("您操作的太快了，请稍后重试"));

                    return;
                }

                await _repeatCommitCache.SetAsync(cacheKey, cacheKey, new Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions
                {
                    SlidingExpiration = TimeSpan.FromMilliseconds(_repeatCommitOptions.Value == null ? 200 : _repeatCommitOptions.Value.RepeatCommitMilliseconds)
                });
            }


            await next();
        }
    }
}
